home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 1
/
Meeting Pearls Vol 1 (1994).iso
/
amok98-106
/
amok105
/
hotkey
/
hotkey.mod
< prev
next >
Wrap
Text File
|
1994-05-03
|
13KB
|
428 lines
(*---------------------------------------------------------------------------
:Program. Hotkey.mod
:Author. Thomas Igracki
:Address. Obstallee 45, 1000 Berlin 20, W-Germany
:E-Mail. T.IGRACKI@BAMP.ZER
:Version. V1.0 28-Apr-92 Thomas Igracki
:Version. first release
:Version. V2.0 21-Dec-92 Thomas Wagner [tom]
:Version. removed some bugs (no ReplyMsg ...)
:Version. and completely revised. Warning:
:Version. Interface has changed!
:Copyright. Thomas Igracki
:Language. Oberon
:Translator. Amiga Oberon 3.00d
:Remark. OS2.04 or higher Only!
---------------------------------------------------------------------------*)
MODULE HotKey;
IMPORT
s: SYSTEM, c: Commodities, e: Exec;
VAR
nb : c.NewBroker;
broker,
filter : c.CxObjPtr;
ComPort : e.MsgPortPtr;
Error - : SHORTINT; (* Look here to determine why Init()/InitX() failed *)
ErrorSet-: LONGSET; (* Look here to determine why AddKey failed *)
CONST
(* Error returns in global variable Error from Init() and InitX() *)
noError * = c.errOk ; (* No error *)
systemError * = c.errSysErr ; (* System error, no memory, etc *)
uniqueError * = c.errDup ; (* uniqueness violation *)
wrongVersion * = c.errVersion; (* didn't understand NewBroker.version *)(* should not appear *)
(* own definitions *)
calledTwice * = -1; (* called Init() or InitX() twice *)
createPortFailed * = -2; (* CreateMsgPort() failed *)
brokerNIL * = -3; (* No Broker created *)
(* Error returns in global variable ErrorSet from AddKey(). NOTE: multiple might be set! *)
filterIsNIL * = c.coErrIsNull ; (* not enough memory to create filter *)
nilAttach * = c.coErrNullAttach; (* someone attached NULL to my list *)
badDescription * = c.coErrBadFilter ; (* a bad filter description was given; wrong hotkey descr. *)
badType * = c.coErrBadType ; (* unmatched type-specific operation *)
(* own definitions *)
noPort * = MAX(LONGSET); (* Call Init() or Initx() first *)
(* Message Types *)
hotkey * = c.cxmIEvent;
command * = c.cxmCommand;
(* Commands *)
cDisable *= c.cmdDisable; (* handled automaticly, you should ignore it *)
cEnable *= c.cmdEnable; (* handled automaticly, you should ignore it *)
cAppear *= c.cmdAppear; (* open your window, if you can *)
cDisappear*= c.cmdDisappear; (* go dormant *)
cKill *= c.cmdKill; (* go away for good *)
cListChg *= c.cmdListChg; (* Someone changed the broker list *)
cUnique *= c.cmdUnique; (* someone tried to create a broker
with your name. Suggest you appear. *)
(*NOTE*)(* the following constants are defined wrong in AmigaOberon 3.00 Interfaces *)
(* Flags for Unique *)
duplicate * = {};
unique * = 0; (* will not allow duplicates *)
notify * = 1; (* sends cUnique to existing broker *)
(****** HotKey/--background-- ******************************************
*
* DESCRIPTION
* This module allows easy access to hotkey-specific functions of the
* commodity.library.
*
* NOTE
* DeleteBroker() and CheckCVersion() are the only procedures which
* are very kind to OS1.x, because ONLY they are supposed to be called on
* Operating Systems other than Release 2+.
*
* Therefore you MUST NOT call any of the module's
* procedures except DeleteBroker() and CheckCVersion() on
* Systems without commodities.library.
*
* In addition the version of commodities.library must be 37
* or higher, because this version is demanded by Oberon 3.00
* Interfaces for the commodities.library
* ( OpenLibrary(commodities.library,37) ).
*
* After version check failed, you may gracefully exit, e.g.
* IF ~ CheckCVersion(0) THEN HALT(20) END;
*
* There should be no need to IMPORT Commodities, because all
* important constants are redefined. Some constants are even
* defined wrong in Interfaces for Oberon3.00!
*
*
* EXAMPLE
* Refer to HotKeyTest for a example how to use this module.
*
* AUTHOR
* Program: V1.0 28-Apr-92 Thomas Igracki
* first release
* V2.0 21-Dec-92 Thomas Wagner [tom]
* removed some bugs (no ReplyMsg ...)
* and completely revised.
* NOTE: ** Interface has changed! **
*
* Autodocs: Thomas Wagner [tom]
*
******************************************************************************)
(****** HotKey/CheckCVersion ******************************************
*
* NAME
* CheckCVersion -- Checks the version of the Commodities.library.
*
* SYNOPSIS
* CheckCVersion (version: SHORTINT): BOOLEAN;
*
* FUNCTION
* Check whether the required version is available.
*
* INPUTS
* version - The required version. 0 to check if there is
* any usable version of commodities.library available.
* (See NOTE!).
*
* RESULT
* BOOLEAN - TRUE if Commodity has the required version or higher
* FALSE if not available
*
* NOTE
* V36 is considered out of date. So if you use the Interfaces for
* commodity.library delivered with Oberon3.00 (or later versions)
* CheckCVersion(0) will return FALSE!
*
******************************************************************************)
PROCEDURE CheckCVersion*(version: SHORTINT):BOOLEAN;
BEGIN
IF c.base = NIL THEN RETURN(FALSE) END;
RETURN(c.base.version >= version);
END CheckCVersion;
(****** HotKey/Init ******************************************
*
* NAME
* Init -- Initiate a broker.
* InitX -- Initiate a broker (extended parameters).
*
* SYNOPSIS
* InitX (name,title,descr: ARRAY OF CHAR;
* unique : SET;
* window : BOOLEAN;
* pri : SHORTINT ): SHORTINT;
*
* Init (name,title,descr: ARRAY OF CHAR): SHORTINT;
*
* FUNCTION
* Initiates some structures needed by all other procedures
* of this module and installs a broker.
*
* INPUTS
* name - The name of the broker. You should not exceed the length
* defined in Commodities.nameLen.
* title - Name, version, ... of the commodity. You should not exceed
* the maximum length defined in Commodities.titleLen.
* descr - A short summary of the functionality of this commodity.
* You should not exceed the length defined in
* Commodities.descrLength.
*
* Only for InitX():
*
* unique - Set to one or more of Flags for Unique.
* Init: set to {notify}.
* window - Set this to TRUE when your commodity is able to open
* a window. If this is set to FALSE the Show/Hide gadgets
* of the exchange program are deactivated.
* Init: set to TRUE.
* pri - The priority of the broker. Init: set to 0.
*
* RESULT
* SHORTINT - A positive number is the Signalbit for hotkey
* activity. -1 indicates an error. See the global
* readonly variable Error for the cause.
* Here are some important errors:
* systemError : usually no memory
* calledTwice : called this routine twice
* brokerNIL : usually already another broker with
* same name
*
* NOTES
* - After Init() or InitX() you must call Activate() to activate
* the broker.
* - You can't call Init() twice.
*
* SEE ALSO
* DeleteBroker()
*
******************************************************************************)
PROCEDURE InitX* (name,title,descr: ARRAY OF CHAR;
unique : SET;
window : BOOLEAN;
pri : SHORTINT ): SHORTINT;
(* $CopyArrays- *)
VAR err: LONGINT;
BEGIN
IF ComPort # NIL THEN Error := calledTwice; RETURN -1 END;
ComPort := e.CreateMsgPort();
IF ComPort = NIL THEN Error := createPortFailed; RETURN -1 END;
nb.version := c.nbVersion;
nb.name := s.ADR(name);
nb.title := s.ADR(title);
nb.descr := s.ADR(descr);
nb.unique := unique;
IF window THEN nb.flags := {c.showHide} END;
nb.pri := pri;
nb.port := ComPort;
broker := c.CxBroker (nb,err);
IF err = c.errOk THEN
IF broker # NIL THEN
RETURN ComPort.sigBit;
ELSE
Error := brokerNIL; RETURN -1;
END;
ELSE
Error := SHORT(SHORT(err)); RETURN -1;
END;
END InitX;
PROCEDURE Init* (name,title,descr: ARRAY OF CHAR): SHORTINT;
(* $CopyArrays- *)
BEGIN
RETURN(InitX(name,title,descr,{notify},TRUE,0));
END Init;
(****** HotKey/AddKey ******************************************
*
* NAME
* AddKey -- Add a hotkey description to the broker
*
* SYNOPSIS
* AddKey (descr: ARRAY OF CHAR; ID: LONGINT):BOOLEAN
*
* FUNCTION
* Adds the given hotkey to the broker.
*
* INPUTS
* descr - containing the hotkey description
* ID - any number to recognize this hotkey. Not
* used by the module or by the operating system.
*
* RESULT
* BOOLEAN - indicates the success of the hotkey installation. If
* FALSE, ErrorSet contains the error code.
* Note: Multiple error code bits are possible.
* The most important error:
* badDescription: wrong hotkey description
*
* SEE ALSO
* GetCMsg()
*
******************************************************************************)
PROCEDURE AddKey* (descr: ARRAY OF CHAR; ID: LONGINT):BOOLEAN; (* $CopyArrays- *)
VAR filter: c.CxObjPtr;
BEGIN
ErrorSet := LONGSET{};
IF ComPort = NIL THEN ErrorSet := LONGSET{noPort}; RETURN(FALSE) END;
filter := c.CxFilter (s.ADR(descr));
(* No NIL-check of filter, because addErr = c.coErrIsNull in this case *)
ErrorSet := c.CxObjError(filter);
IF ErrorSet # LONGSET{} THEN RETURN(FALSE) END;
c.AttachCxObj (filter, c.CxSender (ComPort, ID));
c.AttachCxObj (filter, c.CxTranslate (NIL));
c.AttachCxObj (broker,filter);
RETURN(TRUE);
END AddKey;
(****** HotKey/Activate ******************************************
*
* NAME
* Activate -- (De)activates hotkeys
*
* SYNOPSIS
* Activate (ON: BOOLEAN)
*
* FUNCTION
* This function activates or deactivates the broker and its hotkeys.
*
* INPUTS
* ON - TRUE to activate, FALSE to deactivate
*
******************************************************************************)
PROCEDURE Activate* (ON: BOOLEAN);
BEGIN s.SETREG (0,c.ActivateCxObj (broker,s.VAL(SHORTINT,ON)));
END Activate;
(****** HotKey/GetCMsg ******************************************
*
* NAME
* GetCMsg -- Get commodity message
*
* SYNOPSIS
* GetCMsg(VAR type: LONGSET; VAR id: INTEGER):BOOLEAN
*
* FUNCTION
* If you get the signal (value returned by Init()) then you must
* call GetCMsg() to determine which hotkey was pressed or which
* command was sent.
*
* INPUTS
* VAR type - Contains hotkey if an Hotkey was pressed or command
* if a command was sent. Note: cDisable and cEnable
* are handled automatically by this module. So you
* should ignore them, except you want to add some
* more functionality to them.
* VAR id - An integer value to store the id of a hotkey (if there
* is any Msg). Only valid if type equals command.
*
* RESULT
* BOOLEAN - TRUE if there was a Msg and type and id is valid.
* Call GetCMsg() again, because there might be more Msg's.
*
* EXAMPLE
* IMPORT Exec, HotKey;
* VAR HotID : LONGINT;
* HotType: LONGSET;
* HotSig : SHORTINT;
* Signals: SHORTINT;
* ...
* IF ~HotKey.CheckCVersion(0) THEN HALT(20) END;
* HotSig := HotKey.Init(...);
* ...
* Signals := Exec.Wait(LONGSET{HotSig});
* ...
* IF HotSig IN Signals THEN
* WHILE HotKey.GetCMsg(HotType,HotID) DO
* IF HotKey.hotkey IN HotType THEN
* CASE HotID OF
* ...
* END; (* CASE *)
* ELSIF HotKey.command IN HotType THEN
* CASE HotID OF
* hot.cAppear : (* ShowInterface *) |
* hot.cDisappear: (* HideInterface *) |
* hot.cKill : (* Quit *) |
* hot.cUnique : (* ShowInterface or Quit *) |
* ELSE (* ignore cDisable and cEnable *)
* END; (* CASE *)
* END; (* IF *)
* END; (* WHILE *)
* END; (* IF *)
*
* For a full example see HotKeyTest.mod.
*
******************************************************************************)
PROCEDURE GetCMsg*(VAR type: LONGSET; VAR id: LONGINT):BOOLEAN;
VAR msg : s.ADDRESS; (* should be c.CxMsgPtr, but CxMsg is NO expansion of Msg *)
BEGIN
IF ComPort = NIL THEN RETURN(FALSE) END;
msg := e.GetMsg (ComPort);
IF msg # NIL THEN
type := c.CxMsgType(msg);
id := c.CxMsgID(msg);
e.ReplyMsg(msg);
IF command IN type THEN
CASE id OF
cDisable : Activate(FALSE) |
cEnable : Activate(TRUE) |
ELSE
END;
END;
RETURN(TRUE)
ELSE
RETURN(FALSE);
END;
END GetCMsg;
(****** HotKey/DeleteBroker ******************************************
*
* NAME
* DeleteBroker -- Removes a broker
*
* SYNOPSIS
* DeleteBroker()
*
* FUNCTION
* This function removes the broker (and all attached hotkeys) and
* closes the MsgPort.
*
* NOTES
* This function is automatically called. No need to call it
* yourself except you want to delete the broker earlier.
*
* SEE ALSO
* Init()
*
******************************************************************************)
PROCEDURE DeleteBroker*;
VAR msg : e.MessagePtr;
BEGIN
IF c.base # NIL THEN (* Skip these library calls if OS < 2.04 *)
c.DeleteCxObjAll (broker) ; broker := NIL;
IF ComPort # NIL THEN
REPEAT
msg:=e.GetMsg(ComPort);
IF msg # NIL THEN e.ReplyMsg(msg) END;
UNTIL msg = NIL;
END;
e.DeleteMsgPort (ComPort) ; ComPort := NIL;
END;
END DeleteBroker;
CLOSE
DeleteBroker
END HotKey.